#ifndef XGAME_H
#define XGAME_H

#include "DXDevice.h"

#include "LoadingManager.h"
#include "Shader.h"
#include "Common.h"
#include "BasicTimer.h"
#include "GameState.h"
#include "Texture.h"
#include "Sprite.h"
#include "TouchManager.h"
//huy.vuquang: add sound manager
#include "SoundEngine/SoundManager.h"
//huy end
#include <vector>
class Game : public Singleton<Game>
{
private:
	BasicTimer^ timer;
	std::vector<GameState*> stateStack;
	std::vector<GameState*> stateToDelete;
public:
	static void Init(void* params[])
	{
		if(instance == NULL)
		{
			instance = new Game();
			instance->timer = ref new BasicTimer();
			DXDevice::Init(params);
			LoadingManager::Init();
			ShaderManager::Init();
			TextureManager::Init();
			SpriteManager::Init();
			TouchManager::Init();
			SoundManager::Init();
		}
	}
	void OnResume()
	{
		DXDevice::GetInstance()->Resume();
	}
	void OnSuspend()
	{
		DXDevice::GetInstance()->Suspend();
	}
	void OnExit()
	{
		LoadingManager::Release();
		ShaderManager::Release();
		TextureManager::Release();
		SpriteManager::Release();
		TouchManager::Release();
		DXDevice::GetInstance()->Release();
	}
	void PushState(GameState* state)
	{
		stateStack.push_back(state);
		state->Init();
	}
	void PopState()
	{
		if(stateStack.size() > 0)
		{
			stateToDelete.push_back(stateStack.back());
			stateStack.pop_back();
		}
	}
	void SwitchState(GameState* state)
	{
		PopState();
		PushState(state);
	}
	GameState* GetCurrentState()
	{
		if(stateStack.size() > 0)
		{
			return stateStack.back();
		}
		else
		{
			return NULL;
		}
	}
	int GetStateCount()
	{
		return stateStack.size();
	}
	GameState* GetState(int index)
	{
		if(stateStack.size() > index && index >= 0)
		{
			return stateStack[index];
		}
		else
		{
			return NULL;
		}
	}
	void Update()
	{
		timer->Update();
		TouchManager::GetInstance()->ProcessQueue();
		GameState* state = GetCurrentState();
		if(state)
		{
			state->Update(timer->Total, timer->Delta);
			//DXDevice::GetInstance()->StartCommandChecking();
			state->Render();
			//DXDevice::GetInstance()->StopCommandChecking();
			DXDevice::GetInstance()->FlipBuffer();
		}
		if(stateToDelete.size() > 0)
		{
			for(int i = stateToDelete.size() - 1;i>=0;i--)
			{
				stateToDelete.back()->Release();
				SafeDelete(stateToDelete.back());
				stateToDelete.pop_back();
			}
		}
		TouchManager::GetInstance()->PostUpdate();
	}
};
#endif